001    package net.sf.xdc.processing;
002    
003    /*
004     *  Copyright 2005-2006 Jens Voß.
005     *
006     *  Licensed under the GNU Lesser General Public License (the "License");
007     *  you may not use this file except in compliance with the License.
008     *  You may obtain a copy of the License at
009     *
010     *       http://opensource.org/licenses/lgpl-license.php
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    import java.io.File;
020    import java.io.FileNotFoundException;
021    import java.io.FileReader;
022    import java.io.IOException;
023    import java.io.Reader;
024    import java.io.StringWriter;
025    import java.util.Iterator;
026    import java.util.SortedMap;
027    import java.util.TreeMap;
028    
029    import net.sf.xdc.util.IOUtils;
030    import net.sf.xdc.util.Logging;
031    import org.apache.log4j.Logger;
032    
033    /**
034     * This class represents a "package" of sources. This is essentially a
035     * directory containing one or more XML files to be processed by XDC.
036     *
037     * @author Jens Voß
038     * @since 0.5
039     * @version 0.5
040     */
041    public class XdcPackage {
042    
043      private static final Logger LOG = Logging.getLogger();
044    
045      private String name;
046      private String summaryText;
047      private SortedMap xdcSources = new TreeMap();
048    
049      /**
050       * Public constructor.
051       *
052       * @param name The name of the package. This amounts to the last part of
053       *         the source directory path.
054       */
055      public XdcPackage(String name) {
056        this.name = name;
057      }
058    
059      /**
060       * Getter method for this <code>XdcPackage</code>'s name.
061       *
062       * @return The name of this <code>XdcPackage</code>
063       */
064      public String getName() {
065        return name;
066      }
067    
068      /**
069       * This method is used to register an <code>XdcSource</code> with this
070       * <code>XdcPackage</code>.
071       *
072       * @param xdcSource An <code>XdcSource</code> object to be registered with
073       *         this <code>XdcPackage</code>
074       */
075      public void addSource(XdcSource xdcSource) {
076        xdcSources.put(xdcSource.getFile().getName(), xdcSource);
077      }
078    
079      /**
080       * This method is used to unregister an <code>XdcSource</code> from this
081       * <code>XdcPackage</code>.
082       *
083       * @param xdcSource An <code>XdcSource</code> object to be unregistered from
084       *         this <code>XdcPackage</code>
085       */
086      public void removeSource(XdcSource xdcSource) {
087        xdcSources.remove(xdcSource);
088      }
089    
090      /**
091       * This method retrieves all registered <code>XdcSource</code> objects.
092       *
093       * @return An array of all <code>XdcSource</code> objects registered with
094       *          this <code>XdcPackage</code>
095       */
096      public XdcSource[] getXdcSources() {
097        return (XdcSource[]) xdcSources.values().toArray(new XdcSource[xdcSources.size()]);
098      }
099    
100      /**
101       * This method retrieves a particular <code>XdcSource</code> object
102       * from this <code>XdcPackage</code> by its (non-qualified) name.
103       *
104       * @param sourceName The name of the <code>XdcSource</code> to be
105       *        retrieved
106       * @return The <code>XdcSource</code> of this <code>XdcPackage</code>
107       *         with the name <code>sourceName</code> 
108       */
109      public XdcSource getXdcSource(String sourceName) {
110        return (XdcSource) xdcSources.get(sourceName);
111      }
112    
113      /**
114       * This method retrieves the relevant package summary file text. This text is
115       * the portion between the opening and the closing <body> tag of
116       * a file named <em>xdc-package.html</em> which is placed in this
117       * <code>XdcPackage</code>'s source directory.
118       *
119       * @return The relevant text from the package summary file. Note that this
120       *          text is returned "raw", i.e. with XDC tags not yet resolved.
121       */
122      public String getSummaryText() {
123        if (summaryText == null) {
124          for (Iterator iter = xdcSources.values().iterator(); iter.hasNext();) {
125            XdcSource source = (XdcSource) iter.next();
126            File packageFile = new File(source.getFile().getParentFile(), "xdc-package.html");
127            if (packageFile.exists()) {
128              Reader in = null;
129              try {
130                in = new FileReader(packageFile);
131                StringWriter out = new StringWriter();
132                IOUtils.copy(in, out);
133                StringBuffer buf = out.getBuffer();
134                int pos1 = buf.indexOf("<body>");
135                int pos2 = buf.lastIndexOf("</body>");
136                if (pos1 >= 0 && pos1 < pos2) {
137                  summaryText = buf.substring(pos1 + 6, pos2);
138                }
139                else {
140                  summaryText = "";
141                }
142              }
143              catch (FileNotFoundException e) {
144                LOG.error(e.getMessage(), e);
145                summaryText = "";
146              }
147              catch (IOException e) {
148                LOG.error(e.getMessage(), e);
149                summaryText = "";
150              }
151              finally {
152                if (in != null) {
153                  try {
154                    in.close();
155                  }
156                  catch (IOException e) {
157                    LOG.error(e.getMessage(), e);
158                  }
159                }
160              }
161              break;
162            }
163            else {
164              summaryText = "";
165            }
166          }
167        }
168        return summaryText;
169      }
170    
171    }